/*
 * Copyright 2011 Romain Gilles
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.jvdb;

import java.sql.Date;
import java.util.Calendar;

/**
 * convert a {@code Date} into the following String format: yyyy/MM/dd
 */
class DateConverter<T extends java.util.Date> implements Converter {
    private static final int FORMAT_SIZE = 10;
    private T value;
    private Calendar calendar;

//    static final TimeZone DEFAULT_TIME_ZONE = TimeZone.getTimeZone("GMT+0");
//    static final Locale DEFAULT_LOCALE = Locale.ENGLISH;

    DateConverter(T value, Calendar calendar) {
        this.value = value;
        this.calendar = calendar;
    }

    final public String convert() {
        Calendar cal = calendar == null ? newCalendar(value.getTime()) : calendar;
        StringBuilder result = new StringBuilder(getFormatSize());
        result.append('\'');
        return doConvert(cal, result).append('\'').toString();
    }

    @Override
    public String toString() {
        return convert();
    }

    int getFormatSize() {
        return FORMAT_SIZE;
    }

    StringBuilder doConvert(Calendar cal, StringBuilder result) {
        return format(cal, result);
    }

    private static Calendar newCalendar(long time) {
        Calendar result = Calendar.getInstance();
        result.setTimeInMillis(time);
        return result;
    }

    static StringBuilder format(Calendar cal, StringBuilder result) {
        result.append(cal.get(Calendar.YEAR)).append('/');
        append2DigitField(result, cal, Calendar.MONTH, 1).append('/');
        append2DigitField(result, cal, Calendar.DAY_OF_MONTH);
        return result;
    }

    static StringBuilder append2DigitField(StringBuilder result, Calendar cal, int field) {
        return append2DigitField(result, cal, field, 0);
    }

    static StringBuilder append2DigitField(StringBuilder result, Calendar cal, int field, int offset) {
        int fieldValue = cal.get(field) + offset;
        if (fieldValue < 10)
            result.append('0');
        result.append(fieldValue);
        return result;
    }

    static DateConverter<Date> newInstance(Date value) {
        return newInstance(value, null);
    }

    static DateConverter<Date> newInstance(Date value, Calendar cal) {
        return new DateConverter<Date>(value, cal);
    }
}
